package com.innovation.ic.cyz.base.service.cyz.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Strings;
import com.innovation.ic.cyz.base.mapper.cyz.RepairOrderMapper;
import com.innovation.ic.cyz.base.mapper.cyz.RepairOrderTypeHeadMapper;
import com.innovation.ic.cyz.base.mapper.cyz.RepairOrderTypeMapper;
import com.innovation.ic.cyz.base.model.cyz.RepairOrderType;
import com.innovation.ic.cyz.base.model.cyz.RepairOrderTypeHead;
import com.innovation.ic.cyz.base.pojo.variable.cyz.repair_order_type.FirstLevelRepairOrderTypeQueryRespPojo;
import com.innovation.ic.cyz.base.pojo.variable.cyz.repair_order_type.RepairOrderTypeRespPojo;
import com.innovation.ic.cyz.base.pojo.global.ServiceResult;
import com.innovation.ic.cyz.base.pojo.constant.Constants;
import com.innovation.ic.cyz.base.pojo.constant.repairOrderType.RepairOrderTypeConstant;
import com.innovation.ic.cyz.base.pojo.variable.cyz.repair_order_type.RepairOrderTypeListRespPojo;
import com.innovation.ic.cyz.base.pojo.variable.cyz.repair_order_type.RepairOrderTypeListResultPojo;
import com.innovation.ic.cyz.base.pojo.enums.RepairOrderTypeLevelEnum;
import com.innovation.ic.cyz.base.pojo.variable.cyz.repair_order_type_head.RepairOrderTypeFaeListRespPojo;
import com.innovation.ic.cyz.base.service.cyz.RepairOrderTypeService;
import com.innovation.ic.cyz.base.vo.cyz.repairOrderType.RepairOrderTypeAddVo;
import com.innovation.ic.cyz.base.vo.cyz.repairOrderType.RepairOrderTypeEditVo;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @desc   工单分类接口具体实现类
 * @author linuo
 * @time   2022年9月15日13:39:23
 */
@Service
@Transactional
public class RepairOrderTypeServiceImpl extends ServiceImpl<RepairOrderTypeMapper, RepairOrderType> implements RepairOrderTypeService {
    private static final Logger log = LoggerFactory.getLogger(RepairOrderTypeServiceImpl.class);

    @Resource
    private RepairOrderTypeMapper repairOrderTypeMapper;

    @Resource
    private RepairOrderMapper repairOrderMapper;

    @Resource
    private RepairOrderTypeHeadMapper repairOrderTypeHeadMapper;

    /**
     * 查询工单分类信息
     * @return 返回工单分类信息
     */
    @Override
    public ServiceResult<JSONArray> queryRepairOrderTypeList() {
        JSONArray result = new JSONArray();

        // 查询一级工单分类数据
        QueryWrapper<RepairOrderType> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(RepairOrderTypeConstant.CLASS_LEVEL_FIELD, RepairOrderTypeLevelEnum.FIRST.getCode());
        List<RepairOrderType> repairOrderTypes = repairOrderTypeMapper.selectList(queryWrapper);
        if(repairOrderTypes != null && repairOrderTypes.size() > 0){
            for(RepairOrderType repairOrderType : repairOrderTypes){
                JSONObject jsonObject = new JSONObject();
                jsonObject.put(Constants.ID, repairOrderType.getId());
                jsonObject.put(RepairOrderTypeConstant.CLASS_NAME, repairOrderType.getClassName());

                // 根据一级分类id查询二级分类
                QueryWrapper<RepairOrderType> secondClassQueryWrapper = new QueryWrapper<>();
                secondClassQueryWrapper.eq(RepairOrderTypeConstant.PARENT_ORDER_ID_FIELD, repairOrderType.getId());
                List<RepairOrderType> secondRepairOrderTypes = repairOrderTypeMapper.selectList(secondClassQueryWrapper);
                if(secondRepairOrderTypes != null && secondRepairOrderTypes.size() > 0){
                    JSONArray secondClassJsonArrary = new JSONArray();
                    for(RepairOrderType secondRepairOrderType : secondRepairOrderTypes){
                        JSONObject secondClass = new JSONObject();
                        secondClass.put(Constants.ID, secondRepairOrderType.getId());
                        secondClass.put(RepairOrderTypeConstant.CLASS_NAME, secondRepairOrderType.getClassName());

                        // 根据二级分类id查询三级分类
                        QueryWrapper<RepairOrderType> thirdClassQueryWrapper = new QueryWrapper<>();
                        thirdClassQueryWrapper.eq(RepairOrderTypeConstant.PARENT_ORDER_ID_FIELD, secondRepairOrderType.getId());
                        List<RepairOrderType> thirdRepairOrderTypes = repairOrderTypeMapper.selectList(thirdClassQueryWrapper);
                        if(thirdRepairOrderTypes != null && thirdRepairOrderTypes.size() > 0){
                            JSONArray thirdClassJsonArrary = new JSONArray();
                            for(RepairOrderType thirdRepairOrderType : thirdRepairOrderTypes){
                                JSONObject thirdClass = new JSONObject();
                                thirdClass.put(Constants.ID, thirdRepairOrderType.getId());
                                thirdClass.put(RepairOrderTypeConstant.CLASS_NAME, thirdRepairOrderType.getClassName());
                                thirdClassJsonArrary.add(thirdClass);
                            }
                            secondClass.put("children", thirdClassJsonArrary);
                        }
                        secondClassJsonArrary.add(secondClass);
                    }
                    jsonObject.put("children", secondClassJsonArrary);
                }

                result.add(jsonObject);
            }
        }

        ServiceResult<JSONArray> serviceResult = new ServiceResult<>();
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        serviceResult.setResult(result);
        return serviceResult;
    }

    /**
     * 获取FAE列表
     * @return 返回查询结果
     */
    @Override
    public ServiceResult<List<RepairOrderTypeFaeListRespPojo>> getFaeList() {
        List<RepairOrderTypeFaeListRespPojo> list = repairOrderTypeHeadMapper.getFaeList();

        ServiceResult<List<RepairOrderTypeFaeListRespPojo>> serviceResult = new ServiceResult<>();
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        serviceResult.setResult(list);
        return serviceResult;
    }

    /**
     * 获取一级分类
     * @return 返回查询结果
     */
    @Override
    public ServiceResult<List<FirstLevelRepairOrderTypeQueryRespPojo>> getFirstTypeList() {
        List<FirstLevelRepairOrderTypeQueryRespPojo> result = repairOrderTypeMapper.getFirstTypeList();

        ServiceResult<List<FirstLevelRepairOrderTypeQueryRespPojo>> serviceResult = new ServiceResult<>();
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        serviceResult.setResult(result);
        return serviceResult;
    }

    /**
     * 工单分类编辑
     * @param repairOrderTypeEditVo 工单分类编辑的vo类
     * @return 返回编辑结果
     */
    @Override
    public ServiceResult<Boolean> edit(RepairOrderTypeEditVo repairOrderTypeEditVo) {
        Boolean result = Boolean.FALSE;
        String message = null;

        /*
         *   判断三级分类是否存在，不存在且三级分类名称参数不为空时添加三级分类，存在时若三级分类名称参数不为空返回错误信息
         *   1.查询三级分类数据
         *   2.判断三级分类数据是否存在，不存在时添加三级分类数据
         *   3.三级分类存在时只能更新三级分类负责人，不可以更新三级分类名称
         */
        RepairOrderType secondRepairOrderType = getChildRepairOrderTypeInfoByParentId(repairOrderTypeEditVo.getId());
        if(secondRepairOrderType != null){
            RepairOrderType thirdRepairOrderType = getChildRepairOrderTypeInfoByParentId(secondRepairOrderType.getId());
            if(thirdRepairOrderType != null){
                // 更新三级分类负责人
                if(!Strings.isNullOrEmpty(repairOrderTypeEditVo.getThirdClassHead())){
                    thirdRepairOrderType.setHeadId(repairOrderTypeEditVo.getThirdClassHead());
                    int i = repairOrderTypeMapper.updateById(thirdRepairOrderType);
                    if(i > 0){
                        log.info("更新三级分类负责人成功");
                    }
                }
            }else{
                if(!Strings.isNullOrEmpty(repairOrderTypeEditVo.getThirdClassName())){
                    // 添加三级分类数据
                    RepairOrderType repairOrderType = new RepairOrderType();
                    repairOrderType.setClassName(repairOrderTypeEditVo.getThirdClassName());
                    repairOrderType.setClassLevel(RepairOrderTypeLevelEnum.THIRD.getCode());
                    repairOrderType.setParentOrderId(secondRepairOrderType.getId());
                    if(!Strings.isNullOrEmpty(repairOrderTypeEditVo.getThirdClassHead())){
                        repairOrderType.setHeadId(repairOrderTypeEditVo.getThirdClassHead());
                    }
                    int insert = repairOrderTypeMapper.insert(repairOrderType);
                    if(insert > 0){
                        log.info("添加三级分类数据成功");
                    }
                }
            }

            /* 处理二级分类数据
             * 1.判断二级分类数据是否存在，不存在时添加二级分类数据
             * 2.二级分类存在时只能更新二级分类负责人
             */
            // 更新二级分类负责人
            if(!Strings.isNullOrEmpty(repairOrderTypeEditVo.getSecondClassHead())){
                secondRepairOrderType.setHeadId(repairOrderTypeEditVo.getSecondClassHead());
                int i = repairOrderTypeMapper.updateById(secondRepairOrderType);
                if(i > 0){
                    log.info("更新二级分类负责人成功");
                }
            }
        }else{
            if(!Strings.isNullOrEmpty(repairOrderTypeEditVo.getSecondClassName())){
                // 添加二级分类数据
                RepairOrderType repairOrderType = new RepairOrderType();
                repairOrderType.setClassName(repairOrderTypeEditVo.getSecondClassName());
                repairOrderType.setClassLevel(RepairOrderTypeLevelEnum.SECOND.getCode());
                repairOrderType.setParentOrderId(repairOrderTypeEditVo.getId());
                if(!Strings.isNullOrEmpty(repairOrderTypeEditVo.getSecondClassHead())){
                    repairOrderType.setHeadId(repairOrderTypeEditVo.getSecondClassHead());
                }
                int insert = repairOrderTypeMapper.insert(repairOrderType);
                if(insert > 0){
                    log.info("添加二级分类数据成功");
                }
            }
        }

        // 根据id更新一级分类负责人信息
        if(!Strings.isNullOrEmpty(repairOrderTypeEditVo.getFirstClassHead())){
            RepairOrderType repairOrderType = new RepairOrderType();
            repairOrderType.setHeadId(repairOrderTypeEditVo.getFirstClassHead());

            UpdateWrapper<RepairOrderType> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq(Constants.ID, repairOrderTypeEditVo.getId());

            int update = repairOrderTypeMapper.update(repairOrderType, updateWrapper);
            if(update > 0){
                log.info("更新一级分类负责人成功");
                result = Boolean.TRUE;
                message = ServiceResult.UPDATE_SUCCESS;
            }
        }

        ServiceResult<Boolean> serviceResult = new ServiceResult<>();
        serviceResult.setSuccess(result);
        serviceResult.setResult(result);
        serviceResult.setMessage(message);
        return serviceResult;
    }

    /**
     * 工单分类信息获取
     * @param id 工单分类id
     * @return 返回结果
     */
    @Override
    public ServiceResult<RepairOrderTypeRespPojo> info(Long id) {
        Boolean result = Boolean.FALSE;
        String message = ServiceResult.SELECT_FAIL;

        RepairOrderTypeRespPojo repairOrderTypeRespPojo = new RepairOrderTypeRespPojo();
        RepairOrderType repairOrderType = repairOrderTypeMapper.selectById(id);
        repairOrderTypeRespPojo.setId(id);

        // 一级分类名称
        repairOrderTypeRespPojo.setFirstClassName(repairOrderType.getClassName());
        // 一级分类负责人id
        repairOrderTypeRespPojo.setFirstClassHeadId(repairOrderType.getHeadId());

        RepairOrderType secondRepairOrderType = getChildRepairOrderTypeInfoByParentId(repairOrderType.getId());
        if(secondRepairOrderType != null){
            // 二级分类名称
            repairOrderTypeRespPojo.setSecondClassName(secondRepairOrderType.getClassName());
            // 二级分类负责人
            repairOrderTypeRespPojo.setSecondClassHeadId(secondRepairOrderType.getHeadId());

            RepairOrderType thirdRepairOrderType = getChildRepairOrderTypeInfoByParentId(secondRepairOrderType.getId());
            if(thirdRepairOrderType != null){
                // 三级分类名称
                repairOrderTypeRespPojo.setThirdClassName(thirdRepairOrderType.getClassName());
                // 三级分类负责人
                repairOrderTypeRespPojo.setThirdClassHeadId(thirdRepairOrderType.getHeadId());
            }
        }

        ServiceResult<RepairOrderTypeRespPojo> serviceResult = new ServiceResult<>();
        serviceResult.setSuccess(result);
        serviceResult.setMessage(message);
        serviceResult.setResult(repairOrderTypeRespPojo);
        return serviceResult;
    }

    /**
     * 工单分类列表查询
     * @return 返回工单分类列表数据
     */
    @Override
    public ServiceResult<RepairOrderTypeListResultPojo> queryList(Integer pageNo, Integer pageSize) {
        RepairOrderTypeListResultPojo result = new RepairOrderTypeListResultPojo();

        List<RepairOrderTypeListRespPojo> resultList = new ArrayList<>();

        // 分页查询分类级别为1的工单分类数据
        Map<String, Object> map = new HashMap<>();
        map.put(RepairOrderTypeConstant.CLASS_LEVEL_FIELD, RepairOrderTypeLevelEnum.FIRST.getCode());
        map.put(Constants.PAGE_NO, pageNo);
        map.put(Constants.PAGE_SIZE, pageSize);
        List<RepairOrderType> list = repairOrderTypeMapper.selectRepairOrderTypeList(map);
        if(list != null && list.size() > 0){
            for(RepairOrderType repairOrderType : list){
                RepairOrderTypeListRespPojo repairOrderTypeListRespPojo = new RepairOrderTypeListRespPojo();
                repairOrderTypeListRespPojo.setId(repairOrderType.getId());
                // 一级分类名称
                repairOrderTypeListRespPojo.setFirstClassName(repairOrderType.getClassName());
                // 一级分类负责人
                repairOrderTypeListRespPojo.setFirstClassHead(getRepairOrderTypeHeadNamesByIds(repairOrderType.getHeadId()));

                RepairOrderType secondRepairOrderType = getChildRepairOrderTypeInfoByParentId(repairOrderType.getId());
                if(secondRepairOrderType != null){
                    // 二级分类名称
                    repairOrderTypeListRespPojo.setSecondClassName(secondRepairOrderType.getClassName());
                    // 二级分类负责人
                    repairOrderTypeListRespPojo.setSecondClassHead(getRepairOrderTypeHeadNamesByIds(secondRepairOrderType.getHeadId()));

                    RepairOrderType thirdRepairOrderType = getChildRepairOrderTypeInfoByParentId(secondRepairOrderType.getId());
                    if(thirdRepairOrderType != null){
                        // 三级分类名称
                        repairOrderTypeListRespPojo.setThirdClassName(thirdRepairOrderType.getClassName());
                        // 三级分类负责人
                        repairOrderTypeListRespPojo.setThirdClassHead(getRepairOrderTypeHeadNamesByIds(thirdRepairOrderType.getHeadId()));
                    }
                }

                resultList.add(repairOrderTypeListRespPojo);
            }
        }

        // 查询一级分类数量
        Integer count = repairOrderTypeMapper.selectFirstClassTypeCount();
        result.setCount(count);
        result.setData(resultList);

        ServiceResult<RepairOrderTypeListResultPojo> serviceResult = new ServiceResult<>();
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setResult(result);
        return serviceResult;
    }

    /**
     * 根据父级工单分类id获取下级工单分类数据
     * @param parentId 父级工单分类id
     * @return 返回查询结果
     */
    private RepairOrderType getChildRepairOrderTypeInfoByParentId(Long parentId){
        QueryWrapper<RepairOrderType> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(RepairOrderTypeConstant.PARENT_ORDER_ID_FIELD, parentId);
        List<RepairOrderType> repairOrderTypes = repairOrderTypeMapper.selectList(queryWrapper);
        if(repairOrderTypes != null && repairOrderTypes.size() > 0){
            return repairOrderTypes.get(0);
        }
        return null;
    }

    /**
     * 根据id集合获取负责人姓名
     * @param headIds 负责人id集合
     * @return 返回查询结果
     */
    private String getRepairOrderTypeHeadNamesByIds(String headIds){
        String headNames = null;

        if(!Strings.isNullOrEmpty(headIds)){
            String[] split = headIds.split(",");
            for(String id : split){
                RepairOrderTypeHead repairOrderTypeHead = repairOrderTypeHeadMapper.selectById(id);
                if(repairOrderTypeHead != null && !Strings.isNullOrEmpty(repairOrderTypeHead.getRealName())){
                    headNames = repairOrderTypeHead.getRealName() + "、";
                }
            }
        }

        if(headNames != null && headNames.endsWith("、")){
            headNames = headNames.substring(0, headNames.length() - 1);
        }

        return headNames;
    }

    /**
     * 工单分类删除
     * @param id 工单分类id
     * @return 返回删除结果
     */
    @Override
    public ServiceResult<Boolean> delete(Long id) {
        // 判断工单分类是否有工单在使用,若有的话,当前工单分类不允许删除
        Boolean result = judgeRepairOrderTypeIfUse(id);
        if(result){
            ServiceResult<Boolean> serviceResult = new ServiceResult<>();
            serviceResult.setResult(Boolean.FALSE);
            serviceResult.setSuccess(Boolean.FALSE);
            serviceResult.setMessage("当前工单分类已有工单在使用,无法删除,请知悉");
            return serviceResult;
        }

        int i = repairOrderTypeMapper.deleteById(id);
        if(i > 0){
            log.info("工单分类删除成功,删除id为[{}]", id);

            // 删除下级工单分类数据
            deleteChildRepairOrderData(id);
        }

        ServiceResult<Boolean> serviceResult = new ServiceResult<>();
        serviceResult.setResult(Boolean.TRUE);
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setMessage(ServiceResult.DELETE_SUCCESS);
        return serviceResult;
    }

    /**
     * 删除下级工单分类数据
     * @param firstRepairOrderTypeId 一级工单分类id
     */
    private void deleteChildRepairOrderData(Long firstRepairOrderTypeId) {
        // 查询二级工单分类id集合
        List<Long> secondRepairOrderTypeIdList = repairOrderTypeMapper.selectChildRepairOrderTypeIdList(firstRepairOrderTypeId);
        if(secondRepairOrderTypeIdList != null && secondRepairOrderTypeIdList.size() > 0){
            for(Long secondRepairOrderTypeId : secondRepairOrderTypeIdList){
                // 查询三级工单分类id集合
                List<Long> thirdRepairOrderTypeIdList = repairOrderTypeMapper.selectChildRepairOrderTypeIdList(secondRepairOrderTypeId);
                if(thirdRepairOrderTypeIdList != null && thirdRepairOrderTypeIdList.size() > 0){
                    repairOrderTypeMapper.deleteBatchIds(thirdRepairOrderTypeIdList);
                }
                repairOrderTypeMapper.deleteById(secondRepairOrderTypeId);
            }
        }
    }

    /**
     * 判断工单分类是否有工单在使用
     * @param id 工单分类id
     * @return 返回结果
     */
    private Boolean judgeRepairOrderTypeIfUse(Long id) {
        Boolean result = Boolean.FALSE;

        List<Long> idList = new ArrayList<>();
        idList.add(id);

        // 根据id查询下属工单分类的id集合
        List<Long> secondRepairOrderTypeIds = repairOrderTypeMapper.selectChildRepairOrderTypeIdList(id);
        if(secondRepairOrderTypeIds != null && secondRepairOrderTypeIds.size() > 0){
            idList.addAll(secondRepairOrderTypeIds);
            for(Long secondRepairOrderTypeId : secondRepairOrderTypeIds){
                List<Long> thirdRepairOrderTypeIds = repairOrderTypeMapper.selectChildRepairOrderTypeIdList(secondRepairOrderTypeId);
                if(thirdRepairOrderTypeIds != null && thirdRepairOrderTypeIds.size() > 0){
                    idList.addAll(thirdRepairOrderTypeIds);
                }
            }
        }

        int count = repairOrderMapper.selectUseRepairOrderTypeDataCount(idList);
        if(count > 0){
            result = Boolean.TRUE;
        }

        return result;
    }

    /**
     * 工单分类添加
     * @param repairOrderTypeAddVo 工单分类添加的vo类
     * @return 返回工单分类添加结果
     */
    @Override
    public ServiceResult<Boolean> add(RepairOrderTypeAddVo repairOrderTypeAddVo) {
        Boolean result = Boolean.FALSE;

        String message;

        // 保存一级分类信息
        Long firstClassId = saveRepairOrderTypeData(repairOrderTypeAddVo.getFirstClassName(), RepairOrderTypeLevelEnum.FIRST.getCode(), repairOrderTypeAddVo.getFirstClassHead(), null);
        if(firstClassId != null){
            log.info("一级分类id为:[{}]", firstClassId);
            result = Boolean.TRUE;
            message = ServiceResult.INSERT_SUCCESS;

            if(!Strings.isNullOrEmpty(repairOrderTypeAddVo.getSecondClassName())){
                // 保存二级分类信息
                Long secondClassId = saveRepairOrderTypeData(repairOrderTypeAddVo.getSecondClassName(), RepairOrderTypeLevelEnum.SECOND.getCode(), repairOrderTypeAddVo.getSecondClassHead(), firstClassId);
                if(secondClassId != null){
                    log.info("二级分类id为:[{}]", secondClassId);

                    if(!Strings.isNullOrEmpty(repairOrderTypeAddVo.getThirdClassName())){
                        Long thirdClassId = saveRepairOrderTypeData(repairOrderTypeAddVo.getThirdClassName(), RepairOrderTypeLevelEnum.THIRD.getCode(), repairOrderTypeAddVo.getThirdClassHead(), secondClassId);
                        log.info("三级分类id为:[{}]", thirdClassId);
                    }

                }
            }
        }else{
            message = ServiceResult.INSERT_FAIL;
        }

        ServiceResult<Boolean> serviceResult = new ServiceResult<>();
        serviceResult.setResult(result);
        serviceResult.setSuccess(result);
        serviceResult.setMessage(message);
        return serviceResult;
    }

    /**
     * 保存工单分类数据
     * @param className 分类名称
     * @param classLevel 分类级别
     * @param classHead 分类负责人
     * @param parentOrderId 父级分类id
     * @return 返回工单id
     */
    private Long saveRepairOrderTypeData(String className, Integer classLevel, String classHead, Long parentOrderId){
        RepairOrderType repairOrderType = new RepairOrderType();
        repairOrderType.setClassName(className);
        repairOrderType.setClassLevel(classLevel);
        repairOrderType.setHeadId(classHead);
        if(parentOrderId != null){
            repairOrderType.setParentOrderId(parentOrderId);
        }
        int insert = repairOrderTypeMapper.insert(repairOrderType);
        if(insert > 0){
            return repairOrderType.getId();
        }
        return null;
    }
}